package com.qw.flutter.bugly;

import android.content.Context;
import android.os.Handler;
import android.text.TextUtils;
import android.util.Log;

import androidx.annotation.NonNull;

import com.qw.flutter.bugly.bean.BuglyInitResultInfo;
import com.qw.flutter.bugly.callback.BuglyCatchCrashCallback;
import com.qw.flutter.bugly.util.JsonUtil;
import com.qw.flutter.bugly.util.MapUtil;
import com.tencent.bugly.Bugly;
import com.tencent.bugly.beta.Beta;
import com.tencent.bugly.beta.UpgradeInfo;
import com.tencent.bugly.beta.upgrade.UpgradeListener;
import com.tencent.bugly.crashreport.CrashReport;

import java.util.HashMap;
import java.util.Map;

import io.flutter.BuildConfig;
import io.flutter.embedding.engine.plugins.FlutterPlugin;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugin.common.MethodChannel.MethodCallHandler;
import io.flutter.plugin.common.MethodChannel.Result;

/**
 * FlutterBuglyPlugin
 */
public class FlutterBuglyPlugin implements FlutterPlugin, MethodCallHandler {
    private MethodChannel channel;
    private Context appContext;
    private BuglyCatchCrashCallback buglyCatchCrashCallback;

    @Override
    public void onAttachedToEngine(@NonNull FlutterPluginBinding flutterPluginBinding) {
        appContext = flutterPluginBinding.getApplicationContext();
        channel = new MethodChannel(flutterPluginBinding.getBinaryMessenger(), "com.qw.flutter.plugins/bugly");
        channel.setMethodCallHandler(this);
    }

    @Override
    public void onMethodCall(@NonNull MethodCall call, @NonNull Result result) {
        if ("initBugly".equals(call.method)) {
            if (call.hasArgument("appId")) {
                //自动初始化开关
                //true表示app启动自动初始化升级模块; false不会自动初始化; 开发者如果担心sdk初始化影响app启动速度，可以设置为false，
                //在后面某个时刻手动调用Beta.init(getApplicationContext(),false);
                if (call.hasArgument("autoInit")) {
                    Beta.autoInit = call.hasArgument("autoInit");
                } else {
                    Beta.autoInit = true;
                }

                //升级SDK默认是开启热更新能力的，如果你不需要使用热更新，可以将这个接口设置为false。
                if (call.hasArgument("enableHotfix")) {
                    Beta.enableHotfix = call.argument("enableHotfix");
                } else {
                    Beta.enableHotfix = false;
                }

                //自动检查更新开关
                //true表示初始化时自动检查升级; false表示不会自动检查升级,需要手动调用Beta.checkUpgrade()方法;
                if (call.hasArgument("autoCheckUpgrade")) {
                    Beta.autoCheckUpgrade = call.argument("autoCheckUpgrade");
                }

                //设置Wifi下自动下载
                //如果你想在Wifi网络下自动下载，可以将这个接口设置为true，默认值为false。
                if (call.hasArgument("autoDownloadOnWifi")) {
                    Beta.autoDownloadOnWifi = call.argument("autoDownloadOnWifi");
                }

                //设置启动延时（默认延时3s），APP启动1s后初始化SDK，避免影响APP启动速度;
                if (call.hasArgument("initDelay")) {
                    int delay = call.argument("initDelay");
                    Beta.initDelay = delay * 1000;
                } else {
                    Beta.initDelay = 3 * 1000;
                }

                //设置是否显示消息通知
                //如果你不想在通知栏显示下载进度，你可以将这个接口设置为false，默认值为true。
                if (call.hasArgument("enableNotification")) {
                    Beta.enableNotification = call.argument("enableNotification");
                }

                //升级检查周期设置
                //设置升级检查周期为60s(默认检查周期为0s)，60s内SDK不重复向后台请求策略);
                if (call.hasArgument("upgradeCheckPeriod")) {
                    int period = call.argument("upgradeCheckPeriod");
                    Beta.upgradeCheckPeriod = period * 1000;
                } else {
                    Beta.upgradeCheckPeriod = 20 * 1000;
                }

                //设置开启显示打断策略
                // 已经确认过的弹窗在APP下次启动自动检查更新时会再次显示;
                if (call.hasArgument("showInterruptedStrategy")) {
                    Beta.showInterruptedStrategy = call.argument("showInterruptedStrategy");
                } else {
                    Beta.showInterruptedStrategy = true;
                }

                //设置是否显示弹窗中的apk信息
                //如果你使用我们默认弹窗是会显示apk信息的，如果你不想显示可以将这个接口设置为false
                if (call.hasArgument("canShowApkInfo")) {
                    Beta.canShowApkInfo = call.argument("canShowApkInfo");
                }

                if (call.hasArgument("customUpgrade")) {
                    boolean customUpgrade = call.argument("customUpgrade");
                    /*在application中初始化时设置监听，监听策略的收取*/
                    Beta.upgradeListener = customUpgrade ? new UpgradeListener() {
                        @Override
                        public void onUpgrade(int ret, UpgradeInfo strategy, boolean isManual, boolean isSilence) {
                            Map<String, Object> data = new HashMap<>(2);
                            data.put("upgradeInfo", JsonUtil.toJson(MapUtil.deepToMap(strategy)));
                            channel.invokeMethod("onCheckUpgrade", data);
                        }
                    } : null;
                }

                //自定义数据size
                int customExtraDataSize = 0;
                if (call.hasArgument("customExtraDataSize")) {
                    customExtraDataSize = call.argument("customExtraDataSize");
                }

                buglyCatchCrashCallback = new BuglyCatchCrashCallback(customExtraDataSize);
                CrashReport.UserStrategy strategy = new CrashReport.UserStrategy(appContext);
                strategy.setCrashHandleCallback(buglyCatchCrashCallback);

                String appId = call.argument("appId").toString();
                Bugly.init(appContext, appId, BuildConfig.DEBUG, strategy);

                if (call.hasArgument("channel")) {
                    String channel = call.argument("channel");
                    if (!TextUtils.isEmpty(channel)) {
                        Bugly.setAppChannel(appContext, channel);
                    }
                }

                result(result, getResultBean(true, appId, "Bugly 初始化成功"));
            } else {
                result(result, getResultBean(false, null, "Bugly appId不能为空"));
            }
        } else if ("setUserId".equals(call.method)) {
            if (call.hasArgument("userId")) {
                String userId = call.argument("userId");
                Bugly.setUserId(appContext, userId);
            }
            result(result);
        } else if ("setUserTag".equals(call.method)) {
            if (call.hasArgument("userTag")) {
                Integer userTag = call.argument("userTag");
                if (userTag != null) {
                    Bugly.setUserTag(appContext, userTag);
                }
            }
            result(result);
        } else if ("putUserData".equals(call.method)) {
            if (call.hasArgument("key") && call.hasArgument("value")) {
                String userDataKey = call.argument("key");
                String userDataValue = call.argument("value");
                Bugly.putUserData(appContext, userDataKey, userDataValue);
            }
            result(result);
        } else if ("putCustomExtraData".equals(call.method)) {
            if (call.hasArgument("key") && call.hasArgument("value")) {
                String customDataKey = call.argument("key");
                String customDataValue = call.argument("value");
                if (buglyCatchCrashCallback != null) {
                    buglyCatchCrashCallback.putCustomExtraData(customDataKey, customDataValue);
                }
            }
            result(result);
        } else if ("checkUpgrade".equals(call.method)) {
            //用户手动点击检查，非用户点击操作请传false
            boolean isManual = false;
            //是否显示弹窗等交互，[true:没有弹窗和toast] [false:有弹窗或toast]
            boolean isSilence = false;
            if (call.hasArgument("isManual")) {
                isManual = call.argument("isManual");
            }
            if (call.hasArgument("isSilence")) {
                isSilence = call.argument("isSilence");
            }
            //手动检查更新（用于设置页面中检测更新按钮的点击事件）
            Beta.checkUpgrade(isManual, isSilence);
            result(result);
        } else if ("getUpgradeInfo".equals(call.method)) {
            //获取本地已有升级策略（非实时，可用于界面红点展示）
            UpgradeInfo strategy = Beta.getUpgradeInfo();
            result(result, strategy);
        } else if ("postCatchedException".equals(call.method)) {
            postException(call);
            result(result);
        } else {
            result.notImplemented();
        }
    }

    private void postException(MethodCall call) {
        String message = "";
        String detail = null;
        Map<String, String> map = null;
        if (call.hasArgument("crash_message")) {
            message = call.argument("crash_message");
        }

        if (call.hasArgument("crash_detail")) {
            detail = call.argument("crash_detail");
        }

        if (call.hasArgument("crash_data")) {
            map = call.argument("crash_data");
        }

        if (TextUtils.isEmpty(detail)) {
            return;
        }
        CrashReport.postException(8, "Flutter Exception", message, detail, map);

    }

    private void result(Result result, Object object) {
        if (result != null) {
            if (object == null) {
                result.success(null);
            } else {
                result.success(JsonUtil.toJson(MapUtil.deepToMap(object)));
            }
        }
    }

    private void result(Result result) {
        if (result != null) {
            result.success(null);
        }
    }

    private BuglyInitResultInfo getResultBean(boolean isSuccess, String appId, String msg) {
        BuglyInitResultInfo bean = new BuglyInitResultInfo();
        bean.setSuccess(isSuccess);
        bean.setAppId(appId);
        bean.setMessage(msg);
        return bean;
    }

    @Override
    public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) {
        channel.setMethodCallHandler(null);
    }
}
